#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <sys/types.h>
#include <string>
#include <sys/syscall.h>
using namespace std;

// 定义一个条件变量
pthread_cond_t cond;
// 定义一个互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 当前不用，但是接口需要
// 定义全局退出变量
volatile bool quit=false;

void *waitCommand(void *args)
{
    while (!quit)
    {
        // 执行了下面的代码，证明某一种条件不就绪（目前没有场景），需要该线程进行等待
        // 三个线程，都会在条件变量下进行排队
        pthread_cond_wait(&cond, &mutex); // 让对应的线程进行等待，等待被唤醒
        cout << "thread id : " << pthread_self() << " run..." << endl;
    }
}

int main()
{
    pthread_cond_init(&cond, nullptr);
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, waitCommand, nullptr);
    pthread_create(&t2, nullptr, waitCommand, nullptr);
    pthread_create(&t3, nullptr, waitCommand, nullptr);

    while (true)
    {
        char n = 'a';
        cout << "请输入你的command(c/q): ";
        cin >> n;
        if (n == 'c')
            // pthread_cond_signal(&cond);
            pthread_cond_broadcast(&cond);
        else
        {
            quit=true;
            break;
        }

        usleep(1000);
    }

    // 取消不了
    cout<<"main thread quit"<<endl;
    pthread_cond_broadcast(&cond);
    // pthread_cancel(t1);
    // pthread_cancel(t2);
    // pthread_cancel(t3);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_cond_destroy(&cond);
    return 0;
}

// // 一把锁会不会有死锁问题
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// int cnt = 100;

// void *startRountine(void *args)
// {
//     string name = static_cast<char *>(args);
//     while (true)
//     {
//         pthread_mutex_lock(&mutex);
//         pthread_mutex_lock(&mutex);
//         cout << name << "count : " << cnt-- << endl;
//         pthread_mutex_unlock(&mutex);
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t t1, t2;

//     pthread_create(&t1, nullptr, startRountine, (void *)"thread 1");
//     pthread_create(&t2, nullptr, startRountine, (void *)"thread 2");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     return 0;
// }
